package com.yu.mall.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSONObject;
import com.yu.mall.dto.ProductExcelDto;
import com.yu.mall.dto.ProductInfoDto;
import com.yu.mall.entity.ProductInfo;
import com.yu.mall.enums.StatusEnum;
import com.yu.mall.service.ProductService;
import com.yu.mall.util.BeanHelper;
import com.yu.mall.util.ResultUtils;
import com.yu.mall.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("productManage")
@Api(tags = "后台商品管理", value = "后台商品管理")
@Slf4j
public class ProductManageController {

    @Autowired
    private ProductService productService;

    @PostMapping("listQuery")
    @ApiOperation(value = "后台查询商品列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "nameWord", value = "商品名称，模糊查询", required = false, dataType = "String"),
            @ApiImplicitParam(name = "typeCode", value = "类型编号", required = false, dataType = "String"),
            @ApiImplicitParam(name = "skuId", value = "商品编号", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态，不传查所有，1:上架，2:下架", required = false, dataType = "String"),
            @ApiImplicitParam(name = "isLaobao", value = "是否是劳保，不传查所有", required = false, dataType = "boolean"),
            @ApiImplicitParam(name = "pageNum", value = "页码，默认1", required = false, dataType = "int",example  = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量，默认10", required = false, dataType = "int",example  = "10"),
            @ApiImplicitParam(name = "minPrice", value = "最低价", required = false, dataType = "String"),
            @ApiImplicitParam(name = "maxPrice", value = "最高价", required = false, dataType = "String"),
            @ApiImplicitParam(name = "orderByType", value = "排序类型,默认排序不传,priceAsc:价格升序，priceDesc:价格降序," +
                    "rateAsc:采购折扣率升序,rateDesc:采购折扣率降序", required = false, dataType = "String")})
    public ResultVO<JSONObject> listQuery(String skuId,String nameWord, String typeCode, String status, Boolean isLaobao,
                                          String minPrice,String maxPrice,String orderByType,Integer pageNum, Integer pageSize) {
        if (null == pageNum || pageNum < 1) {
            pageNum = 1;
        }
        if (null == pageSize || pageSize < 1 || pageSize > 100) {
            pageSize = 10;
        }
        ProductInfoDto reqDto = new ProductInfoDto();
        reqDto.setSkuId(skuId);
        reqDto.setNameWord(nameWord);
        reqDto.setTypeCode(typeCode);
        reqDto.setStatus(status);
        log.info("isLaobao"+isLaobao);
        reqDto.setIsLaobao(isLaobao);
        if(StrUtil.isNotBlank(minPrice)){
            reqDto.setMinPrice(new BigDecimal(minPrice));
        }
        if(StrUtil.isNotBlank(maxPrice)){
            reqDto.setMaxPrice(new BigDecimal(maxPrice));
        }
        reqDto.setOrderByType(orderByType);
        try {
            long count = productService.pageQueryProductCount(reqDto);
            List<ProductInfo> productInfoList = productService.pageQueryProduct(reqDto, pageNum, pageSize);
            JSONObject data = new JSONObject();
            data.put("count", count);
            data.put("productInfoList", productInfoList);
            return ResultUtils.success(data);
        } catch (Exception e) {
            log.error("后台查询商品列表，出错", e);
        }
        return ResultUtils.error("操作失败");
    }

    @PostMapping("getAllType")
    @ApiOperation(value = "查询商品所有分类")
    public ResultVO<Map<String, String>> getAllType() {
        return ResultUtils.success(productService.getAllProductType());
    }

    @PostMapping("addToLb")
    @ApiOperation(value = "添加商品到劳保分类")
    @ApiImplicitParam(name = "skuIds", value = "skuIds，多个skuId英文逗号隔开", required = true, dataType = "String")
    public ResultVO<String> addToLb(String skuIds) {
        if (StrUtil.isBlank(skuIds)) {
            return ResultUtils.error("skuIds为空");
        }
        try {
            List<String> skuIdList = Arrays.asList(skuIds.split(","));
            productService.addToLb(skuIdList);
            return ResultUtils.success(null);
        } catch (Exception e) {
            log.error("添加商品到劳保分类，出错", e);
        }
        return ResultUtils.error("操作失败");
    }

    @PostMapping("removeFromLb")
    @ApiOperation(value = "移除商品到劳保分类")
    @ApiImplicitParam(name = "skuIds", value = "skuIds，多个skuId英文逗号隔开", required = true, dataType = "String")
    public ResultVO<String> removeFromLb(String skuIds) {
        if (StrUtil.isBlank(skuIds)) {
            return ResultUtils.error("skuIds为空");
        }
        try {
            List<String> skuIdList = Arrays.asList(skuIds.split(","));
            productService.removeFromLb(skuIdList);
            return ResultUtils.success(null);
        } catch (Exception e) {
            log.error("移除商品到劳保分类，出错", e);
        }
        return ResultUtils.error("操作失败");
    }

    @PostMapping("offline")
    @ApiOperation(value = "批量下架商品")
    @ApiImplicitParam(name = "skuIds", value = "skuIds，多个skuId英文逗号隔开", required = true, dataType = "String")
    public ResultVO<String> offline(String skuIds) {
        if (StrUtil.isBlank(skuIds)) {
            return ResultUtils.error("skuIds为空");
        }
        try {
            List<String> skuIdList = Arrays.asList(skuIds.split(","));
            productService.updateStatusByIds(skuIdList, StatusEnum.OFF.getCode());
            return ResultUtils.success(null);
        } catch (Exception e) {
            log.error("批量下架商品，出错", e);
        }
        return ResultUtils.error("操作失败");
    }

    @PostMapping("online")
    @ApiOperation(value = "批量上架商品")
    @ApiImplicitParam(name = "skuIds", value = "skuIds，多个skuId英文逗号隔开", required = true, dataType = "String")
    public ResultVO<String> online(String skuIds) {
        if (StrUtil.isBlank(skuIds)) {
            return ResultUtils.error("skuIds为空");
        }
        try {
            List<String> skuIdList = Arrays.asList(skuIds.split(","));
            productService.updateStatusByIds(skuIdList, StatusEnum.ON.getCode());
            return ResultUtils.success(null);
        } catch (Exception e) {
            log.error("批量上架商品，出错", e);
        }
        return ResultUtils.error("操作失败");
    }

    @GetMapping("listDownLoad")
    @ApiOperation(value = "后台商品导出")
    @ApiImplicitParams({@ApiImplicitParam(name = "nameWord", value = "商品名称，模糊查询", required = false, dataType = "String"),
            @ApiImplicitParam(name = "typeCode", value = "类型编号", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态，不传查所有，1:上架，2:下架", required = false, dataType = "String"),
            @ApiImplicitParam(name = "isLaobao", value = "是否是劳保，不传查所有", required = false, dataType = "boolean"),
            @ApiImplicitParam(name = "minPrice", value = "最低价", required = false, dataType = "String"),
            @ApiImplicitParam(name = "maxPrice", value = "最高价", required = false, dataType = "String"),
            @ApiImplicitParam(name = "orderByType", value = "排序类型,默认排序不传,priceAsc:价格升序，priceDesc:价格降序," +
                    "rateAsc:采购折扣率升序,rateDesc:采购折扣率降序", required = false, dataType = "String")})
    public void listDownLoad(String nameWord, String typeCode, String status, Boolean isLaobao,
                          String minPrice, String maxPrice, String orderByType, HttpServletResponse response) {
        ProductInfoDto reqDto = new ProductInfoDto();
        reqDto.setNameWord(nameWord);
        reqDto.setTypeCode(typeCode);
        reqDto.setStatus(status);
        reqDto.setIsLaobao(isLaobao);
        if(StrUtil.isNotBlank(minPrice)){
            reqDto.setMinPrice(new BigDecimal(minPrice));
        }
        if(StrUtil.isNotBlank(maxPrice)){
            reqDto.setMaxPrice(new BigDecimal(maxPrice));
        }
        reqDto.setOrderByType(orderByType);
        long count = productService.pageQueryProductCount(reqDto);
        ExcelWriter writer = ExcelUtil.getBigWriter();
        writer.setSheet("sheet1");
        writer.addHeaderAlias("skuId","skuId");
        writer.addHeaderAlias("typeName","商品分类名称");
        writer.addHeaderAlias("typeCode","商品分类编号");
        writer.addHeaderAlias("brand","商品品牌");
        writer.addHeaderAlias("name","商品名称");
        writer.addHeaderAlias("status","状态");
        writer.addHeaderAlias("isLaobao","是否是劳保分类");
        writer.addHeaderAlias("jdPrice","销售价");
        writer.addHeaderAlias("price","采购价");
        writer.addHeaderAlias("rate","采购折扣率");
        if(count>0){
            for (int i = 0; i < count/1000+1; i++) {
                List<ProductInfo> productInfoList = productService.pageQueryProduct(reqDto, i+1, 1000);
                List<ProductExcelDto> excelList = new ArrayList<>();
                for (ProductInfo item: productInfoList) {
                    ProductExcelDto dto = new ProductExcelDto();
                    BeanHelper.copyProperties(item,dto);
                    excelList.add(dto);
                }
                if(i==0){
                    writer.write(excelList,true);
                }else{
                    writer.write(excelList,false);
                }
            }
        }
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=product.xlsx");
        ServletOutputStream excelOut = null;
        try {
            excelOut = response.getOutputStream();
            writer.flush(excelOut,true);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            writer.close();
        }
        IoUtil.close(excelOut);
    }
}
